#include "HTMLFetcher.h"
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include "Statistics.h"
#include <pthread.h>
#include <csignal>
  
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
//#define STATS


/* MUST USE DIFFERENT HTMLFetcher OBJECTS IN DIFFERENT THREADS!!!! */




using namespace std;


size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
//  struct HTTPFile *out=(struct HTTPFile *)stream;
//  if(out && !out->stream) {
//    /* open file for writing */
//    out->stream=fopen(out->filename.c_str(), "wb");
//    if(!out->stream)
//     return -1; /* failure, can't open file to write */
//  } */
  return fwrite(buffer, size, nmemb, (FILE*)stream); 
}


HTMLFetcher::HTMLFetcher()
{
}

HTMLFetcher::~HTMLFetcher()
{
}

int HTMLFetcher::fetchPage(std::string baseUrl, std::string fileName)
{
		signal (SIGPIPE, SIG_IGN);		
		time_t start;
#ifdef STATS
		start = time(&start);
#endif
	    
		CURL* curl = curl_easy_init();
	    curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
	    curl_easy_setopt(curl, CURLOPT_HEADER, 0);
	    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 0);
	    curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 0);
	    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
	    curl_easy_setopt(curl, CURLOPT_TIMEOUT,10);
	    curl_easy_setopt(curl, CURLOPT_VERBOSE, false);   
	    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
	    curl_easy_setopt(curl, CURLOPT_FAILONERROR, true);
	    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, true);
	    curl_easy_setopt(curl, CURLOPT_MAXFILESIZE, 300*1024);
		CURLcode res;	  

	    if(curl) {
	      string ffile = fileName.substr(0,3).append("/").append(fileName);
	      //cout << "FILENAMEEEEE: "<< ffile << endl;
	      FILE* destiny = fopen(ffile.c_str(), "wb");
	      //httpfile.stream = fopen(fileName.c_str());	      
	      curl_easy_setopt(curl, CURLOPT_URL, baseUrl.c_str());
	      
	      
	      if(destiny != NULL)
	      {
	    	  fprintf(destiny,"%s\n", baseUrl.c_str());
	    	  curl_easy_setopt(curl, CURLOPT_WRITEDATA, destiny);
	    	  res = curl_easy_perform(curl);
	      }
	      else
	    	  res = static_cast<CURLcode>(2);
	      if(CURLE_OK == res) {
	    	  //cout << " Download OK" << endl;
	      }
	      else
	      {
	    	  //cout << "Error: [" << res << "] - " << errorBuffer << endl;
	    	  pthread_mutex_lock(&Statistics::curlErrorMutex);
	    	  Statistics::addCurlError( static_cast<int> (res));
	    	  Statistics::curlErrorReport();
	    	  pthread_mutex_unlock(&Statistics::curlErrorMutex); 
	    	  //cout << "Error on page: " << baseUrl << endl;
	      }
	      if(destiny != NULL)
	    	  fclose(destiny);
	      else
	      {
	    	  //cout << "EU TAVA DANDO SEGFAULT AKI xD" << endl;
	      }
	  }
	     
	    curl_easy_cleanup(curl);
#ifdef STATS
	time_t end = time(&end);
	pthread_mutex_lock(&Statistics::HF_Mutex);
	Statistics::HF_calls++;
	Statistics::HF_time += (end-start);
	pthread_mutex_unlock(&Statistics::HF_Mutex);
#endif
	   return static_cast<int> (res);
	  }	
